﻿using KMSimulator.Model;
using KMSimulator.Utils;
using SharpHook;
using System.Drawing;

namespace KMSimulator
{
    public class KMHelper
    {
        readonly EventSimulator _simulator; //键鼠模拟器

        public KMHelper()
        {
            _simulator = new EventSimulator();
        }

        /// <summary>
        /// 按键输入
        /// </summary>
        /// <param name="keyString">按键内容,</param>
        /// <param name="releaseDelay"></param>
        public void Input(string keyString, int releaseDelay = 100)
        {
            var ks = keyString.Split("+");
            foreach (var k in ks)
            {
                _simulator.SimulateKeyPress(KeyUtils.GetKeyCode(k));
            }
            Thread.Sleep(releaseDelay);
            foreach (var k in ks)
            {
                _simulator.SimulateKeyRelease(KeyUtils.GetKeyCode(k));
            }
        }

        /// <summary>
        /// 输入字符
        /// </summary>
        /// <param name="text"></param>
        public void Input(string text)
        {
            _simulator.SimulateTextEntry(text);
        }

        /// <summary>
        /// 点击
        /// </summary>
        /// <param name="button"></param>
        /// <param name="point"></param>
        /// <param name="releaseDelay"></param>
        public void Input(MouseButton button,  Point point, int releaseDelay = 100)
        {
            if (point == Point.Empty)
            {
                _simulator.SimulateMousePress((SharpHook.Native.MouseButton)button);
                Thread.Sleep(releaseDelay);
                _simulator.SimulateMouseRelease((SharpHook.Native.MouseButton)button);
            }
            else
            {
                _simulator.SimulateMousePress((short)point.X, (short)point.Y, (SharpHook.Native.MouseButton)button);
                Thread.Sleep(releaseDelay);
                _simulator.SimulateMouseRelease((short)point.X, (short)point.Y, (SharpHook.Native.MouseButton)button);
            }
        }

        /// <summary>
        /// 多次点击
        /// </summary>
        /// <param name="button"></param>
        /// <param name="point"></param>
        /// <param name="clicks"></param>
        /// <param name="clickDelay"></param>
        /// <param name="releaseDelay"></param>
        public void Input(MouseButton button, Point point, uint clicks, int clickDelay = 100, int releaseDelay = 100)
        {
            for (int i = 0; i < clicks; i++) 
            {
                Input(button, point, releaseDelay);
                Thread.Sleep(clickDelay);
            }
        }

        /// <summary>
        /// 移动到指定位置
        /// </summary>
        /// <param name="point">移动到的坐标</param>
        /// <param name="relativeToCursor">是否从光标位置相对移动</param>
        public void Move(Point point, bool relativeToCursor = false)
        {
            if(relativeToCursor)
            {
                _simulator.SimulateMouseMovementRelative((short)point.X, (short)point.Y);
            }
            else
            {
                _simulator.SimulateMouseMovement((short)point.X, (short)point.Y);
            }
            
        }

        /// <summary>
        /// 沿路径移动
        /// </summary>
        /// <param name="points">坐标路径</param>
        /// <param name="relativeToCursor">是否从光标位置相对移动</param>
        public void Move(Point[] points, bool relativeToCursor = false)
        {
            foreach (Point point in points) 
            {
                if (relativeToCursor)
                {
                    _simulator.SimulateMouseMovementRelative((short)point.X, (short)point.Y);
                }
                else
                {
                    _simulator.SimulateMouseMovement((short)point.X, (short)point.Y);
                }
            }
        }

        /// <summary>
        /// 按住鼠标键拖拽
        /// </summary>
        /// <param name="button">鼠标按键</param>
        /// <param name="begin">坐标</param>
        /// <param name="end"></param>
        public void Drag(MouseButton button, Point begin, Point end, int delay = 0)
        {
            _simulator.SimulateMousePress((short)begin.X, (short)begin.Y, (SharpHook.Native.MouseButton)button);
            if (delay > 0)
                Thread.Sleep(delay);
            _simulator.SimulateMouseRelease((short)end.X, (short)end.Y, (SharpHook.Native.MouseButton)button);
        }

        /// <summary>
        /// 按住鼠标键拖拽
        /// </summary>
        /// <param name="button"></param>
        /// <param name="points"></param>
        /// <param name="delay"></param>
        public void Drag(MouseButton button, Point[] points, int delay = 0)
        {
            for (int i = 0; i < points.Length; i++)
            {
                if (i == points.Length - 1) break;
                _simulator.SimulateMousePress((short)points[i].X, (short)points[i].Y, (SharpHook.Native.MouseButton)button);
                if (delay > 0)
                    Thread.Sleep(delay);
                _simulator.SimulateMouseRelease((short)points[i + 1].X, (short)points[i + 1].Y, (SharpHook.Native.MouseButton)button);
            }
        }

        /// <summary>
        /// 滚轮
        /// </summary>
        /// <param name="rotation">滚动度数</param>
        /// <param name="direction">方向</param>
        /// <param name="type"></param>
        public void Wheel(short rotation, Direction direction, ScrollType type = ScrollType.UnitScroll)
        {
            _simulator.SimulateMouseWheel(rotation, (SharpHook.Native.MouseWheelScrollDirection)direction, (SharpHook.Native.MouseWheelScrollType)type);
        }
    }
}
